GUI系统之SurfaceFlinger启动过程分析

surfaceFlinger 在init.rc中是作为一个service存在的它声明如下

1
2
3
4
5
service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics drmrpc
onrestart restart zygote

从上面的内容可以看出,surfaceflinger所属的class为main,这和zygote时同级的。但它的启动并不需要带任何参数。同时由于surfaceflinger是service,说明它是单独的可执行程序,程序路径为/system/bin/surfaceflinger 运行在单独的进程里,另外,从最后一行也能看出sf重启时要重启zygote。

Surfaceflinger主程序对应的文件是frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp 所以我们从这个文件入手。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int main(int argc, char** argv) {
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);//限制了binder线程的个数为4

// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();//启动binder线程

// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();//创建SF对象

#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
#endif
set_sched_policy(0, SP_FOREGROUND);

// initialize before clients can connect
flinger->init();//SF的初始化

// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//添加到SM中

// run in this thread
flinger->run();//sf运行起来

return 0;
}

sf的主程序中做了以下事情:
1.初始binder的运行环境
2.创建Sf对象,并对其进行初始化
3.将Sf服务添加到ServiceManger中,以便向其他进程提供服务
4.SF在自己的线程中开始运行

SurfaceFlinger作为服务进程,必然需要通过Binder进行IPC通信,所以在一开始需要对Binder环境进行初始化。接着创建了SurfaceFlinger对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(),
mTransactionFlags(0),
mTransactionPending(false),
mAnimTransactionPending(false),
mLayersRemoved(false),
mRepaintEverything(0),
mRenderEngine(NULL),
mBootTime(systemTime()),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
mAnimCompositionPending(false),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false)
{
// debugging stuff...
char value[PROPERTY_VALUE_MAX];

property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !atoi(value);

property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);

property_get("debug.sf.ddms", value, "0");
mDebugDDMS = atoi(value);
if (mDebugDDMS) {
if (!startDdmConnection()) {
// start failed, and DDMS debugging not enabled
mDebugDDMS = 0;
}
}
}

构造方法很简单,只是都其成员进行初始化,读取一些配置信息,比如是否开启DDMS的调试。
接下来通过init方法对该对象进行初始化。这个初始化过程会做大量比较重要的工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
//sf的初始化方法
void SurfaceFlinger::init() {
status_t err;
Mutex::Autolock _l(mStateLock);

// initialize EGL for the default display
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);//获取默认的显示设备
eglInitialize(mEGLDisplay, NULL, NULL);//为默认的显示设备初始EGL环境

// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));//创建合成对象

// First try to get an ES2 config
err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT,
&mEGLConfig);

if (err != NO_ERROR) {
// If ES2 fails, try ES1
err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(),
EGL_OPENGL_ES_BIT, &mEGLConfig);
}
……
EGLint r,g,b,a;
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_RED_SIZE, &r);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_GREEN_SIZE, &g);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_BLUE_SIZE, &b);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_ALPHA_SIZE, &a);

// get a RenderEngine for the given display / config (can't fail)
mRenderEngine = RenderEngine::create(mEGLDisplay, mEGLConfig);//通过给定的设备创建渲染引擎

// retrieve the EGL context that was selected/created
mEGLContext = mRenderEngine->getEGLContext();//获取EGL context

// figure out which format we got
eglGetConfigAttrib(mEGLDisplay, mEGLConfig,
EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);

LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");

// initialize our non-virtual displays
//初始化所有的非虚拟显示设备
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
// set-up the displays that are already connected
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
// All non-virtual displays are currently considered secure.
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
//为显示设备创建BufferQueue用来管理其帧缓冲区 并通过FramebufferSurface进行管理
sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
sp<DisplayDevice> hw = new DisplayDevice(this,
type, allocateHwcDisplayId(type), isSecure, token,
fbs, bq,
mEGLConfig);//为每个实体设备创建显示设备对象
if (i > DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't get blank/unblank requests
// for displays other than the main display, so we always
// assume a connected display is unblanked.
ALOGD("marking display %d as acquired/unblanked", i);
hw->acquireScreen();
}
mDisplays.add(token, hw);
}
}

// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);//将EGL context和默认的显示设备关联

// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true);//创建绘图延时对象
mEventThread = new EventThread(vsyncSrc);//负责管理绘图延时Vsync信号
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, false);//创建合成延时对象
mSFEventThread = new EventThread(sfVsyncSrc);//负责管理合成延时Vsync信号
mEventQueue.setEventThread(mSFEventThread);

mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

……
}

在init方法中,sf做了以下的事:
1.为默认的显示设备初始EGL环境
2.创建合成对象
3.初始化所有的非虚拟显示设备
4.创建绘图延时Vysnc源 及 合成延时Vysnc源

1
2
3
4
5
6
7
8
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents = eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
MessageQueue::cb_eventReceiver, this);//为sf的vsync信号注册事件回调
}

需要注意的是在main方法中创建的SurfaceFlinger是个强引用对象,所以在第一次调用同时也会会触发onFirstRef方法,这个方法会对SF的mEventQueue成员进行初始化。它是一个MessageQueue对象,负责SF的消息管理。

1
2
3
4
5
6
7
8
9
10
11
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}

void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;//持有sf的引用
mLooper = new Looper(true);//为其创建一个Looper对象
mHandler = new Handler(*this);//创建Handler
}

最后调用sf的run方法,这个方法会进入一个循环,不断等待消息的到来并进行处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}

frameworks/native/services/surfaceflinger/MessageQueue.cpp
void MessageQueue::waitMessage() {
do {
IPCThreadState::self()->flushCommands();
int32_t ret = mLooper->pollOnce(-1);//内部会调用MessageQueue的handleMessage方法对消息进行处理
switch (ret) {
case ALOOPER_POLL_WAKE:
case ALOOPER_POLL_CALLBACK:
continue;
case ALOOPER_POLL_ERROR:
ALOGE("ALOOPER_POLL_ERROR");
case ALOOPER_POLL_TIMEOUT:
// timeout (should not happen)
continue;
default:
// should not happen
ALOGE("Looper::pollOnce() returned unknown status %d", ret);
continue;
}
} while (true);
}

//通过消息的handler对消息进行处理
void MessageBase::handleMessage(const Message&) {
this->handler();
barrier.open();
};

SF的消息来源有两种,一个是Vsync信号,这是通过注册的cb_eventReceiver事件回调来处理的,另一种可能是应用进程或者说客户端的消息,比如创建Layer的请求,就是通过发送消息的方式来处理的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
frameworks/native/services/surfaceflinger/Client.cpp
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
class MessageCreateLayer : public MessageBase {//继承子messagbase
SurfaceFlinger* flinger;
Client* client;
sp<IBinder>* handle;
sp<IGraphicBufferProducer>* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {//实现了handler 这个方法用于接收方处理消息
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
};

sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
坚持原创技术分享,您的支持将鼓励我继续创作!